package com.th.supcom.pds.impl.service.internal.phamapply;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import net.carefx.fc.framework.web.gwt.util.FcUtils;
import net.carefx.framework.exception.BusinessException;
import net.carefx.framework.translate.TranslatorManager;
import net.carefx.framework.util.ConvertUtils;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.th.supcom.pds.domain.pojo.InpPhamApplyDetail;
import com.th.supcom.pds.domain.pojo.InpPhamApplyDetailSummary;
import com.th.supcom.pds.domain.pojo.InpPhamApplyMaster;
import com.th.supcom.pds.domain.pojo.InpPhamApplyPatInfo;
import com.th.supcom.pds.domain.pojo.InpPhamDispenseDetail;
import com.th.supcom.pds.domain.pojo.InpPhamDispenseResult;
import com.th.supcom.pds.domain.vo.InpPhamApplyDetailSummaryVO;
import com.th.supcom.pds.domain.vo.InpPhamApplyDetailVO;
import com.th.supcom.pds.domain.vo.InpPhamDispenseDetailVO;
import com.th.supcom.pds.impl.common.enums.BMSApplyClassEnum;
import com.th.supcom.pds.impl.common.enums.BMSItemClassEnum;
import com.th.supcom.pds.impl.common.enums.BMSRcptOnClassCodeEnum;
import com.th.supcom.pds.impl.common.enums.InpChargeIndicator;
import com.th.supcom.pds.impl.common.enums.InpDispenseIndicator;
import com.th.supcom.pds.impl.common.enums.PhamMaterialTypeIdEnum;
import com.th.supcom.pds.impl.common.utils.ExceptionThrowHelper;
import com.th.supcom.pds.impl.service.internal.phamapply.chain.InpPhamDispenseServiceChain;
import com.th.supcom.pds.impl.service.internal.phamapply.command.PhamDispenseContext;
import com.th.supcom.pds.internal.api.phamapply.InpPhamApplyDetailBasicService;
import com.th.supcom.pds.internal.api.phamapply.InpPhamApplyInfoQueryService;
import com.th.supcom.pds.internal.api.phamapply.InpPhamApplyMasterBasicService;
import com.th.supcom.pds.internal.api.phamapply.InpPhamDispenseDetailBasicService;
import com.th.supcom.pds.internal.api.phamapply.PhamDispenseService;
import com.th.supcom.pds.medicare.api.AdapterBMSChargeService;
import com.th.supcom.pds.medicare.api.AdapterDrugManagerService;
import com.th.supcom.pds.medicare.api.AdapterOrdersService;
import com.th.supcom.pds.medicare.api.AdapterPTSPatientInfoService;

public class PhamDispenseServiceImpl implements PhamDispenseService,ApplicationContextAware
{

    private InpPhamApplyMasterBasicService m_inpPhamApplyMasterBasicService;
    private InpPhamApplyDetailBasicService m_inpPhamApplyDetailBasicService;
    private InpPhamApplyInfoQueryService m_inpPhamApplyInfoQueryService;
    private InpPhamDispenseDetailBasicService m_inpPhamDispenseDetailBasicService;
    private AdapterPTSPatientInfoService m_adapterPTSPatientInfoService;
    private AdapterBMSChargeService m_adapterBMSChargeService;
    private AdapterDrugManagerService m_adapterDrugManagerService;
    private TranslatorManager m_translatorManager;
    private AdapterOrdersService m_adapterOrdersService;
    ApplicationContext m_applicationContext = null;
    String m_inpPhamDispenseServiceChain = null;
    public void setAdapterOrdersService (AdapterOrdersService adapterOrdersService)
    {

        m_adapterOrdersService = adapterOrdersService;
    }
    
    @Override
    public List<InpPhamApplyDetailVO> findInpPhamApplyInfo(
    		InpPhamApplyDetail inpPhamApplyDetail) {
    	// TODO Auto-generated method stub
    	return null;
    }
    
    public void setInpPhamDispenseServiceChain(String inpPhamDispenseServiceChain){
    	m_inpPhamDispenseServiceChain = inpPhamDispenseServiceChain;
    }

    protected InpPhamDispenseServiceChain createInpPhamDispenseChain (){
    	return (InpPhamDispenseServiceChain) m_applicationContext.getBean(m_inpPhamDispenseServiceChain);
    }
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
    		throws BeansException {
    	m_applicationContext = applicationContext;
    }

    public void setInpPhamDispenseDetailBasicService (InpPhamDispenseDetailBasicService inpPhamDispenseDetailBasicService)
    {
        m_inpPhamDispenseDetailBasicService = inpPhamDispenseDetailBasicService;
    }

    public void setAdapterDrugManagerService (AdapterDrugManagerService adapterDrugManagerService)
    {
        m_adapterDrugManagerService = adapterDrugManagerService;
    }

    public void setAdapterBMSChargeService (AdapterBMSChargeService adapterBMSChargeService)
    {
        m_adapterBMSChargeService = adapterBMSChargeService;
    }

    public void setAdapterPTSPatientInfoService (AdapterPTSPatientInfoService adapterPTSPatientInfoService)
    {
        m_adapterPTSPatientInfoService = adapterPTSPatientInfoService;
    }

    public void setInpPhamApplyInfoQueryService (InpPhamApplyInfoQueryService inpPhamApplyInfoQueryService)
    {
        m_inpPhamApplyInfoQueryService = inpPhamApplyInfoQueryService;
    }

    public void setInpPhamApplyDetailBasicService (InpPhamApplyDetailBasicService inpPhamApplyDetailBasicService)
    {
        m_inpPhamApplyDetailBasicService = inpPhamApplyDetailBasicService;
    }

    public void setInpPhamApplyMasterBasicService (InpPhamApplyMasterBasicService inpPhamApplyMasterBasicService)
    {
        m_inpPhamApplyMasterBasicService = inpPhamApplyMasterBasicService;
    }

    public void setTranslatorManager (TranslatorManager translatorManager)
    {
        m_translatorManager = translatorManager;
    }

    @Override
    public List <InpPhamApplyDetailVO> obtainApplyDetailByApplyNoAndDispensary (String applyNo, String dispensary)
    {
        // 先通过请领单据号找到住院摆药请领主单据，获取请领护理单元
        InpPhamApplyMaster applyMaster = m_inpPhamApplyMasterBasicService.getInpPhamApplyMasterByApplyNo (applyNo);
        // 通过请领单据号和摆药药房查询住院摆药请领单据明细
        InpPhamApplyDetail inpPhamApplyDetail = new InpPhamApplyDetail ();
        inpPhamApplyDetail.setExecDispensary (dispensary);
        inpPhamApplyDetail.setApplyNo (applyNo);
        List <InpPhamApplyDetailVO> detailVOList = m_inpPhamApplyDetailBasicService.findInpPhamApplyDetailListByExample (inpPhamApplyDetail);
        // 将请领明细按照药品分组
        List <String> phamStdCodeList = new ArrayList <String> ();
        PhamApplyConvertUtils.convertListToMapByPhamStdCode (detailVOList, phamStdCodeList);
        // 根据药品标准码和当前药房查询药品的基本信息、供药属性和库存
        InpPhamApplyDetailSummaryVO inpPhamApplyDetailSummaryVO = new InpPhamApplyDetailSummaryVO ();
        inpPhamApplyDetailSummaryVO.setPhamStdCodeList (phamStdCodeList);
        inpPhamApplyDetailSummaryVO.setDispensary (dispensary);
        List <InpPhamApplyDetailSummary> phamInfoList = m_inpPhamApplyInfoQueryService.findInpDispensePhamInfo (inpPhamApplyDetailSummaryVO);

        // 标识药品是否可供以及库存是否充足并更新货位信息
        PhamApplyStaticMethod.updateDispenseStockStatus (detailVOList, phamInfoList);
        // 通过护理单元查找患者基本信息、费别
        List <InpPhamApplyPatInfo> currentPatInfos = m_adapterPTSPatientInfoService.obtainPatBasicInfo (applyMaster.getNurseUnit ());
        // 将请领明细按照患者住院流水号分组
        List <Long> paivisitIdList = new ArrayList <Long> ();
        Map <Long, List <InpPhamApplyDetailVO>> patDetailMap = PhamApplyConvertUtils.convertListToMapByPaivisitID (detailVOList, paivisitIdList);
        // 获取预交金
        currentPatInfos = m_adapterBMSChargeService.obtainPatAvailablePrepayment (currentPatInfos);
        // 关联患者住院信息
        detailVOList = getInpPatInfo (currentPatInfos, detailVOList);
        // 计算患者是否欠费
        CheckAdequatePrepayment.isPrepayEnough (patDetailMap, currentPatInfos);
        // 除去相同的医嘱序号和子序号
        detailVOList = PhamApplyStaticMethod.combineDetailByOrderSubNo (detailVOList);
        // 查询摆药请领对应的医嘱内容
        detailVOList = m_adapterOrdersService.findOrderContentByPaivisitAndOrderNo (detailVOList);
        return m_translatorManager.translate (detailVOList);
    }

    /**
     * 更新患者住院信息
     */
    private List <InpPhamApplyDetailVO> getInpPatInfo (List <InpPhamApplyPatInfo> patInfos, List <InpPhamApplyDetailVO> detailVOList)
    {
        List <InpPhamApplyDetailVO> tempList = new ArrayList <InpPhamApplyDetailVO> ();
        Map <Long, InpPhamApplyPatInfo> patMap = PhamApplyConvertUtils.convertPatInfoListToMapByPaivisitId (patInfos);
        for (InpPhamApplyDetailVO vo : detailVOList)
        {
            InpPhamApplyPatInfo patInfo = patMap.get (vo.getPaiVisitId ());
            if (null == patInfo || null == patInfo.getBedNo ())
            {
                continue;
            }

            if (null == patInfo.getAvailablePrepayment ())
            {
                throw new BusinessException ("预交金为空");
            }
            vo.setBedNo (patInfo.getBedNo ());
            vo.setPaiName (patInfo.getPatName ());
            vo.setGender (patInfo.getGender ());
            vo.setChargeType (patInfo.getChargeType ());
            vo.setBalance (patInfo.getAvailablePrepayment ());
            tempList.add (vo);
        }

        return tempList;
    }

    /**
     * 更新患者住院信息
     */
    private List <InpPhamDispenseDetailVO> getInpPatInfoWhenCheckDispense (List <InpPhamApplyPatInfo> patInfos, List <InpPhamDispenseDetailVO> detailVOList)
    {
        List <InpPhamDispenseDetailVO> tempList = new ArrayList <InpPhamDispenseDetailVO> ();
        Map <Long, InpPhamApplyPatInfo> patMap = PhamApplyConvertUtils.convertPatInfoListToMapByPaivisitId (patInfos);
        for (InpPhamDispenseDetailVO vo : detailVOList)
        {
            InpPhamApplyPatInfo patInfo = patMap.get (vo.getPaiVisitId ());
            if (null == patInfo || null == patInfo.getBedNo ())
            {
                continue;
            }
            vo.setBedNo (patInfo.getBedNo ());
            vo.setPatName (patInfo.getPatName ());
            vo.setGender (patInfo.getGender ());
            vo.setChargeType (patInfo.getChargeType ());
            vo.setBalance (patInfo.getAvailablePrepayment ());
            tempList.add (vo);
        }

        return tempList;
    }

    @Override
    public void execPhamApplySheet (List <InpPhamApplyDetailVO> applyList, InpPhamApplyMaster inpPhamApplyMaster, String operator, String dispensary)
    {
        ExceptionThrowHelper.throwIllegalArgumentException (StringUtils.isBlank (dispensary), "当前药房代码不能为空");
        ExceptionThrowHelper.throwIllegalArgumentException (StringUtils.isBlank (operator), "当前操作员不能为空");
        ExceptionThrowHelper.throwIllegalArgumentException (CollectionUtils.isEmpty (applyList), "摆药执行时，前台传入摆药请领明细不能为空");
        ExceptionThrowHelper.throwIllegalArgumentException (null == inpPhamApplyMaster, "摆药执行时，前台传入摆药请领主记录不能为空");
        try
        {
            InpPhamDispenseServiceChain dispenseChain = createInpPhamDispenseChain ();
            dispenseChain.inpPhamDispense (applyList, inpPhamApplyMaster, operator, dispensary);
        }
        catch (Exception e)
        {
            s_logger.error ("调用摆药执行责任链异常:" + e.getLocalizedMessage (), e);
            throw new BusinessException ("调用摆药执行责任链异常:" + e.getLocalizedMessage (), e);
        }

        // 将前台返回药品摆药明细按照药品标准码分组，并计算单种药品的总数量
        // 查询药品的基本信息
        // 查询请领护理单元可冲抵的住院药品请领明细
        // 执行冲抵操作，逐条明细冲抵
        // 查询当前所有患者剩余药品数量，并更新患者药品剩余数量
        // 药品出库
        // 将药品摆药明细按照患者住院流水号分组，并计算本次摆药总费用
        // 住院费用记账
        // 更新住院药品请领摆药标志和费用标志
        // 更新住院药品摆药的摆药标志和费用标志

    }

    @Override
    public void verifyDispenseDetail (InpPhamDispenseResult inpPhamDispenseResult, String operator, String dispensary)
    {
        //获得患者信息
        getPatientInfo (inpPhamDispenseResult);
        //获得药品信息
        getPhamsInfo (inpPhamDispenseResult, dispensary);
        // 1.冲抵药品
        offsetPhams (inpPhamDispenseResult);
        // 2.药品收费
        List <InpPhamDispenseDetailVO> dispenseList = phamDispenseCharge (inpPhamDispenseResult);
        // 3.药品出库

        InpPhamApplyDetail applyDetail = new InpPhamApplyDetail ();
        applyDetail.setApplyNo (dispenseList.get (0).getApplyNo ());
        List <InpPhamApplyDetailVO> inpPhamApplyDetailVOs = m_inpPhamApplyDetailBasicService.findInpPhamApplyDetailListByExample (applyDetail);
        dispenseList = phamStockOut (dispenseList, inpPhamApplyDetailVOs);
        // 4.更新请领明细、执行明细
        modifyDispenseAndAppDetail (operator, dispenseList, inpPhamApplyDetailVOs);

    }

    private void getPhamsInfo (InpPhamDispenseResult inpPhamDispenseResult, String dispensary)
    {
        List <String> phamStdCodeList = new ArrayList <String> ();
        PhamDispenseConvertUtils.convertListToMapByPhamStdCode (inpPhamDispenseResult.getInpPhamDispenseDetailVOs (), phamStdCodeList);
        InpPhamApplyDetailSummaryVO inpPhamApplyDetailSummaryVO = new InpPhamApplyDetailSummaryVO ();
        inpPhamApplyDetailSummaryVO.setPhamStdCodeList (phamStdCodeList);
        inpPhamApplyDetailSummaryVO.setDispensary (dispensary);
        List <InpPhamApplyDetailSummary> phamInfoList = m_inpPhamApplyInfoQueryService.findInpApplyBasicPhamInfo (inpPhamApplyDetailSummaryVO);
        Map <String, List <InpPhamDispenseDetailVO>> dispenseDetailByPhamStdCode = PhamDispenseConvertUtils.convertListToMapByPhamStdCode (inpPhamDispenseResult.getInpPhamDispenseDetailVOs (),
                                                                                                                                           phamStdCodeList);
        Map <String, InpPhamApplyDetailSummary> phamMap;
        phamMap = PhamApplyConvertUtils.convertPhamInfoListToMapByPhamStdCode (phamInfoList);
        Set <Map.Entry <String, InpPhamApplyDetailSummary>> set2 = phamMap.entrySet ();
        for (Iterator <Map.Entry <String, InpPhamApplyDetailSummary>> it = set2.iterator (); it.hasNext ();)
        {
            Map.Entry <String, InpPhamApplyDetailSummary> entry = (Map.Entry <String, InpPhamApplyDetailSummary>) it.next ();
            InpPhamApplyDetailSummary phamInfo = entry.getValue ();
            List <InpPhamDispenseDetailVO> temp = dispenseDetailByPhamStdCode.get (entry.getKey ());
            double totalDispenseAmount = 0;
            for (InpPhamDispenseDetailVO inpPhamDispenseDetailVO : temp)
            {
                totalDispenseAmount += inpPhamDispenseDetailVO.getApplyAmount ();
                inpPhamDispenseDetailVO.setPhamName (phamInfo.getPhamName ());
                inpPhamDispenseDetailVO.setDispensePrice (inpPhamDispenseDetailVO.getFactor () * phamInfo.getPhamPrice ());
                inpPhamDispenseDetailVO.setLeastAbleUnit (phamInfo.getPhamUnit ());
                if (phamInfo.getPhamMaterialType ().equals (PhamMaterialTypeIdEnum.ChineseTraditionMed.getEnumCode ()))
                {
                    inpPhamDispenseDetailVO.setClassOnRcptCode (BMSRcptOnClassCodeEnum.ChinesePatentDrugCharge.getEnumCode ());
                    inpPhamDispenseDetailVO.setItemClass (BMSItemClassEnum.ChinesePatentDrug.getEnumCode ());
                }
                else
                {
                    inpPhamDispenseDetailVO.setClassOnRcptCode (BMSRcptOnClassCodeEnum.WesterMedicineCharge.getEnumCode ());
                    inpPhamDispenseDetailVO.setItemClass (BMSItemClassEnum.WesterMedicine.getEnumCode ());
                }
                inpPhamDispenseDetailVO.setApplyClass (BMSApplyClassEnum.InpPhamDispense.getEnumCode ());
                inpPhamDispenseDetailVO.setAllocation (phamInfo.getAllocation ());
            }
            phamInfo.setDetailSumAmount (totalDispenseAmount);
            phamInfo.setNurseUnit (temp.get (0).getNurseUnit ());
        }
    }

    private void getPatientInfo (InpPhamDispenseResult inpPhamDispenseResult)
    {
        String nurseUnit = inpPhamDispenseResult.getInpPhamDispenseDetailVOs ().get (0).getNurseUnit ();

        // 通过护理单元查找患者基本信息、费别和可用预交金
        List <InpPhamApplyPatInfo> currentPatInfos = m_adapterPTSPatientInfoService.obtainPatBasicInfo (nurseUnit);
        List <Long> paiVisitIdList = new ArrayList <Long> ();
        Map <Long, List <InpPhamDispenseDetailVO>> dispenseDetailMap = PhamDispenseConvertUtils.convertListToMapByPaivisitID (inpPhamDispenseResult.getInpPhamDispenseDetailVOs (), paiVisitIdList);
        // 获取预交金
        currentPatInfos = m_adapterBMSChargeService.obtainPatAvailablePrepayment (currentPatInfos);
        Map <Long, InpPhamApplyPatInfo> patMap;
        patMap = PhamApplyConvertUtils.convertPatInfoListToMapByPaivisitId (currentPatInfos);
        Set <Map.Entry <Long, InpPhamApplyPatInfo>> set = patMap.entrySet ();
        for (Iterator <Map.Entry <Long, InpPhamApplyPatInfo>> it = set.iterator (); it.hasNext ();)
        {
            Map.Entry <Long, InpPhamApplyPatInfo> entry = (Map.Entry <Long, InpPhamApplyPatInfo>) it.next ();
            InpPhamApplyPatInfo patInfo = entry.getValue ();
            List <InpPhamDispenseDetailVO> temp = dispenseDetailMap.get (entry.getKey ());
            if (CollectionUtils.isEmpty (temp))
            {
                continue;
            }
            for (InpPhamDispenseDetailVO inpPhamDispenseDetailVO : temp)
            {
                inpPhamDispenseDetailVO.setPatName (patInfo.getPatName ());
                inpPhamDispenseDetailVO.setPatientId (patInfo.getPatientId ());
                inpPhamDispenseDetailVO.setVisitCount (patInfo.getVisitId ());
                inpPhamDispenseDetailVO.setChargeType (patInfo.getChargeType ());
            }
        }
    }

    private void modifyDispenseAndAppDetail (String operator, List <InpPhamDispenseDetailVO> dispenseList, List <InpPhamApplyDetailVO> inpPhamApplyDetailVOs)
    {
        for (InpPhamApplyDetailVO inpPhamApplyDetailVO : inpPhamApplyDetailVOs)
        {
            inpPhamApplyDetailVO.setChargeIndicator (InpChargeIndicator.Charged.getEnumCode ());
            inpPhamApplyDetailVO.setDispenseIndicator (InpDispenseIndicator.HasDispensed.getEnumCode ());
        }
        for (InpPhamDispenseDetailVO dispenseDetailVO : dispenseList)
        {
            dispenseDetailVO.setChargeIndicator (InpChargeIndicator.Charged.getEnumCode ());
            dispenseDetailVO.setDispenseIndicator (InpDispenseIndicator.HasDispensed.getEnumCode ());
            dispenseDetailVO.setCheckBy (operator);
            dispenseDetailVO.setCheckDatetime (FcUtils.getCurrentServerDateTimeForServer ());
        }
        m_inpPhamApplyDetailBasicService.modifyInpPhamApplyDetailList (PhamDispenseConvertUtils.convertVoToAny (inpPhamApplyDetailVOs, InpPhamApplyDetail.class));

        m_inpPhamDispenseDetailBasicService.modifyInpPhamDispenseDetailList (PhamDispenseConvertUtils.convertVoToAny (dispenseList, InpPhamDispenseDetail.class));
    }

    private List <InpPhamDispenseDetailVO> phamStockOut (List <InpPhamDispenseDetailVO> dispenseList, List <InpPhamApplyDetailVO> inpPhamApplyDetailVOs)
    {
        dispenseList = m_adapterDrugManagerService.phamApplyStockOp (dispenseList);
        // 将执行明细按照请领明细主键分组
        Map <Long, InpPhamDispenseDetailVO> patStockNoMap = PhamDispenseConvertUtils.convertListToMapByApplyId (dispenseList);
        // 药品出库后更新相应请领明细的出入库单据号
        for (InpPhamApplyDetailVO inpPhamApplyDetailVO : inpPhamApplyDetailVOs)
        {
            // 如果清明明细存在对应的执行明细
            if (patStockNoMap.get (inpPhamApplyDetailVO.getInpPhamApplyDetailId ()) != null)
            {
                inpPhamApplyDetailVO.setStockNo (patStockNoMap.get (inpPhamApplyDetailVO.getInpPhamApplyDetailId ()).getStockNo ());
                inpPhamApplyDetailVO.setDispenseIndicator (InpDispenseIndicator.Sorted.getEnumCode ());
            }
        }
        return dispenseList;
    }

    private List <InpPhamDispenseDetailVO> phamDispenseCharge (InpPhamDispenseResult inpPhamDispenseResult)
    {
        List <InpPhamDispenseDetailVO> dispenseList = inpPhamDispenseResult.getInpPhamDispenseDetailVOs ();

        dispenseList = m_adapterBMSChargeService.phamApplyCharge (dispenseList);
        return dispenseList;
    }

    /**
     * 冲抵药品
     * 
     * @param inpPhamDispenseResult
     */
    private void offsetPhams (InpPhamDispenseResult inpPhamDispenseResult)
    {
        List <InpPhamApplyDetailSummary> inpPhamApplyDetailSummaries = inpPhamDispenseResult.getInpPhamApplyDetailSummaries ();
        List <InpPhamApplyDetailVO> offsetDetailVOs = new ArrayList <InpPhamApplyDetailVO> ();
        for (InpPhamApplyDetailSummary summary : inpPhamApplyDetailSummaries)
        {
            InpPhamApplyDetailVO inpPhamApplyDetailVO = new InpPhamApplyDetailVO ();
            inpPhamApplyDetailVO.setNurseUnit (summary.getNurseUnit ());
            inpPhamApplyDetailVO.setPhamStdCode (summary.getPhamStdCode ());
            inpPhamApplyDetailVO.setOffsetSum (summary.getOffsetSumAmount ());
            offsetDetailVOs.add (inpPhamApplyDetailVO);
        }
        m_adapterDrugManagerService.offsetDetailStockOp (offsetDetailVOs);
    }

    @Override
    public List <InpPhamDispenseDetail> findInpPhamDispenseNurse (String dispensary)
    {
        InpPhamDispenseDetail inpPhamDispenseDetail = new InpPhamDispenseDetail ();
        inpPhamDispenseDetail.setDispenseIndicator (InpDispenseIndicator.Sorted.getEnumCode ());
        inpPhamDispenseDetail.setPerformDispensary (dispensary);
        List <InpPhamDispenseDetail> list = m_inpPhamDispenseDetailBasicService.findInpPhamDispenseDetailListByCondition (inpPhamDispenseDetail);
        return m_translatorManager.translate (list);
    }

    @Override
    public InpPhamDispenseResult findInpPhamDispenseByExample (InpPhamDispenseDetailVO inpPhamDispenseDetailVO)
    {
        InpPhamDispenseDetail inpPhamDispenseDetail = new InpPhamDispenseDetail ();
        inpPhamDispenseDetail.setApplyNo (inpPhamDispenseDetailVO.getApplyNo ());
        inpPhamDispenseDetail.setPerformDispensary (inpPhamDispenseDetailVO.getPerformDispensary ());

        List <InpPhamDispenseDetail> list = m_inpPhamDispenseDetailBasicService.findInpPhamDispenseDetailListByExample (inpPhamDispenseDetail);

        // 获得药品汇总信息
        List <InpPhamApplyDetailSummary> inpPhamApplyDetailSummarys = new ArrayList <InpPhamApplyDetailSummary> ();
        Map <String, InpPhamApplyDetailSummary> map = new HashMap <String, InpPhamApplyDetailSummary> ();
        for (InpPhamDispenseDetail detailVO : list)
        {

            if (!map.containsKey (detailVO.getPhamStdCode ()))
            {
                InpPhamApplyDetailSummaryVO summaryVO = new InpPhamApplyDetailSummaryVO ();
                summaryVO.setPhamStdCode (detailVO.getPhamStdCode ());
                summaryVO.setPhamSpec (detailVO.getPhamSpec ());
                summaryVO.setPhamName (detailVO.getPhamName ());
                summaryVO.setTotalCost (detailVO.getCosts ());
                summaryVO.setPhamUnit (detailVO.getDispenseUnit ());
                summaryVO.setDispensary (detailVO.getPerformDispensary ());
                summaryVO.setNurseUnit (detailVO.getNurseUnit ());
                summaryVO.setDetailSumAmount (detailVO.getApplyAmount ().doubleValue ());
                summaryVO.setDispenseInstr (avoidNull (detailVO.getBedNo ()) + "&" + avoidNull (detailVO.getApplyAmount ()));
                map.put (detailVO.getPhamStdCode (), summaryVO);
            }
            else
            {
                InpPhamApplyDetailSummary summary = map.get (detailVO.getPhamStdCode ());
                summary.setDetailSumAmount (summary.getDetailSumAmount () + detailVO.getApplyAmount ().doubleValue ());
                summary.setTotalCost (summary.getTotalCost () + detailVO.getCosts ());
                summary.setDispenseInstr (summary.getDispenseInstr () + avoidNull (detailVO.getBedNo ()) + "&" + avoidNull (detailVO.getApplyAmount ()));
                map.put (detailVO.getPhamStdCode (), summary);
            }
        }

        Set <Entry <String, InpPhamApplyDetailSummary>> set = map.entrySet ();
        for (Entry <String, InpPhamApplyDetailSummary> entry : set)
        {
            InpPhamApplyDetailSummary inpPhamApplyDetailSummary = entry.getValue ();
            inpPhamApplyDetailSummarys.add (inpPhamApplyDetailSummary);
        }
        inpPhamApplyDetailSummarys = m_translatorManager.translate (inpPhamApplyDetailSummarys);
        // 获得可冲抵的药品汇总
        List <InpPhamApplyDetailVO> offsetDetailVOSummarys = m_inpPhamApplyDetailBasicService.findOffsetPhamListSummary (inpPhamApplyDetailSummarys);
        // 将执行汇总数据和冲抵汇总数据做对照
        for (InpPhamApplyDetailSummary inpPhamApplyDetailSummary : inpPhamApplyDetailSummarys)
        {
            for (InpPhamApplyDetailVO offsetDetailVOSummary : offsetDetailVOSummarys)
            {
                if (inpPhamApplyDetailSummary.getPhamStdCode ().equals (offsetDetailVOSummary.getPhamStdCode ()))
                {
                    Integer offsetSum = offsetDetailVOSummary.getOffsetSum () > inpPhamApplyDetailSummary.getDetailSumAmount ().intValue () ? inpPhamApplyDetailSummary.getDetailSumAmount ()
                                                                                                                                                                       .intValue ()
                                                                                                                                           : offsetDetailVOSummary.getOffsetSum ();
                    inpPhamApplyDetailSummary.setOffsetSumAmount (offsetSum);
                }
            }

        }

        List <InpPhamDispenseDetailVO> result = ConvertUtils.convert (InpPhamDispenseDetailVO.class, list);
        // 如果为空直接返回
        if (CollectionUtils.isEmpty (result))
        {
            return null;
        }
        // 通过护理单元查找患者基本信息、费别和可用预交金
        List <InpPhamApplyPatInfo> currentPatInfos = m_adapterPTSPatientInfoService.obtainPatBasicInfo (result.get (0).getNurseUnit ());
        // 获取预交金
        currentPatInfos = m_adapterBMSChargeService.obtainPatAvailablePrepayment (currentPatInfos);
        // 关联患者住院信息
        result = getInpPatInfoWhenCheckDispense (currentPatInfos, result);
        InpPhamDispenseResult inpPhamDispenseResult = new InpPhamDispenseResult ();
        inpPhamDispenseResult.setInpPhamDispenseDetailVOs (m_translatorManager.translate (result));
        inpPhamDispenseResult.setInpPhamApplyDetailSummaries (inpPhamApplyDetailSummarys);
        return inpPhamDispenseResult;
    }

    @Override
    public List <InpPhamApplyDetailSummary> findAvailableDispensary (InpPhamApplyDetailSummary summary)
    {
        List <InpPhamApplyDetailSummary> list = new ArrayList <InpPhamApplyDetailSummary> ();
        if (null == summary)
        {
            return list;
        }
        list.add (summary);
        return m_inpPhamApplyInfoQueryService.findAvailableDispensary (list);
    }

    @Override
    public void cancelPhamApplySheet (InpPhamApplyMaster inpPhamApplyMaster)
    {
        s_logger.debug ("进入cancelPhamApplySheet方法,入参:");
        m_inpPhamApplyMasterBasicService.modifyInpPhamApplyMasterByExample (inpPhamApplyMaster);
    }

    @Override
    public List <InpPhamApplyDetailVO> findInpPhamApplyCancelListByCondition (InpPhamApplyDetailVO inpPhamApplyDetail)
    {
        s_logger.debug ("进入findInpPhamApplyCancelListByCondition方法,入参:");
        return m_inpPhamApplyDetailBasicService.findInpPhamApplyCancelListByCondition (inpPhamApplyDetail);

    }

    @Override
    public List <InpPhamDispenseDetailVO> findInpPhamDispenseDetail (InpPhamDispenseDetail inpPhamDispenseDetail)
    {
        s_logger.debug ("进入findInpPhamDispenseDetail方法,入参:");

        List <InpPhamDispenseDetail> list = m_inpPhamDispenseDetailBasicService.findInpPhamDispenseDetail (inpPhamDispenseDetail);

        List <InpPhamDispenseDetailVO> result = ConvertUtils.convert (InpPhamDispenseDetailVO.class, list);
        // 如果为空直接返回
        if (CollectionUtils.isEmpty (result))
        {
            return result;
        }
        // 通过护理单元查找患者基本信息、费别和可用预交金
        List <InpPhamApplyPatInfo> currentPatInfos = m_adapterPTSPatientInfoService.obtainPatBasicInfo (result.get (0).getNurseUnit ());
        // 获取预交金
        currentPatInfos = m_adapterBMSChargeService.obtainPatAvailablePrepayment (currentPatInfos);
        // 关联患者住院信息
        result = getInpPatInfoWhenCheckDispense (currentPatInfos, result);
        return m_translatorManager.translate (result);

    }

    private String avoidNull (Object object)
    {
        if (object == null)
        {
            return "";
        }
        else
        {
            return object.toString ();
        }
    }

    /** 日志记录器. */
    public static final Logger s_logger = LoggerFactory.getLogger (PhamDispenseServiceImpl.class);

    /** 公司版权信息. */
    public static final String copyright = "Copyright 2014, XuNuo Corporation";

    /** 提交路径. */
    public static final String SCC_BRANCH = "$URL$";

    /** 提交日期. */
    public static final String SCC_LAST_MODIFICATION_DATE = "$Date$";

    /** 最终修改人员. */
    public static final String SCC_LAST_MODIFIER_NAME = "$Author$";

    /** 最终版本号. */
    public static final String SCC_REVISION = "$Revision$";
}
